/**
 * Copyright (C) 2013, Easiio, Inc.
 * All Rights Reserved.
 */
package com.regvision.contacts.utils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.regvision.contacts.R;
import com.regvision.contacts.domain.ContactDataModel;
import com.regvision.contacts.domain.ContactModel;
import com.regvision.contacts.domain.EMailModel;
import com.regvision.contacts.domain.PhoneModel;
import com.regvision.contacts.widget.sort.CharacterParser;

import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.net.Uri;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.text.TextUtils;

public class ContactsUtils {

	protected final static String TAG = "ContactsUtils";

	/** 汉字转换成拼音的类 */
	protected static CharacterParser characterParser = new CharacterParser();

	public static Uri Uri_Contact = Uri
			.parse("content://com.android.contacts/contacts");

	private static final String SORT_KEY_ORDER = "sort_key COLLATE LOCALIZED ASC";

	public static final String PERSONAL_QUERY_SELECTION = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
			+ " LIKE ? || '%'"
			+ " OR "
			+ ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
			+ " LIKE '%' || ' ' || ? || '%'"
			+ " OR "
			+ ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
			+ " LIKE '+' || ? || '%'"
			+ " OR "
			+ ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
			+ " LIKE '(' || ? || '%'";

	public static Uri getPeopleUri() {
		return ContactsContract.Contacts.CONTENT_URI;
	}

	public static Uri getContactPhoneUri() {
		return ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
	}

	public static Uri getContactEmailUri() {
		return ContactsContract.CommonDataKinds.Email.CONTENT_URI;
	}

	public static Intent getCreateNewContactIntent(Context context,
			String contactName, String contactNumber) {
		Intent i = new Intent(Intent.ACTION_INSERT);
		i.setType(ContactsContract.Contacts.CONTENT_TYPE);
		i.putExtra(ContactsContract.Intents.Insert.NAME, contactName);
		i.putExtra(ContactsContract.Intents.Insert.PHONE, contactNumber);
		return i;
	}

	public static Intent getAddToContactIntent(Context context,
			String contactNumber) {
		Intent i = new Intent(Intent.ACTION_INSERT_OR_EDIT);
		i.setType(ContactsContract.Contacts.CONTENT_ITEM_TYPE);
		i.putExtra(ContactsContract.Intents.Insert.PHONE, contactNumber);
		i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
		return i;
	}

	/**
	 * 获取联系人列表
	 * 
	 * @return
	 */
	public static List<ContactModel> getContacts(Context context) {

		// 组织数据源
		List<ContactModel> models = new ArrayList<ContactModel>();

		ContentResolver contentResolver = context.getContentResolver();
		Cursor cursor = contentResolver.query(Uri_Contact, null, null, null,
				null);
		while (cursor.moveToNext()) {
			ContactModel model = new ContactModel();
			model.id = cursor.getString(cursor.getColumnIndex(ContactModel.ID));
			model.name = cursor.getString(cursor
					.getColumnIndex(ContactModel.NAME));
			model.photo = cursor.getInt(cursor
					.getColumnIndex(ContactModel.PHOTO));
			model.number = cursor.getString(cursor
					.getColumnIndex(ContactModel.NUMBER));
			model.sortKey = cursor.getString(cursor
					.getColumnIndex(ContactModel.SORT_KEY));
			model.starred = cursor.getString(cursor
					.getColumnIndex(ContactModel.STARRED));
			model.lookupKey = cursor.getString(cursor
					.getColumnIndex(ContactModel.LOOKUP_KEY));
			if (TextUtils.isEmpty(model.name))
				continue;
			if (!model.name.equals("")) {
				model.sortLetters = characterParser.getSelling(model.name)
						.toUpperCase();
				if (!RegexValidateUtil.checkChar(model.sortLetters.substring(0,
						1))) {
					model.sortLetters = "#" + model.sortLetters;
				}
			}
			models.add(model);
		}
		LogUtil.i(TAG, models.toString());
		cursor.close(); // 关闭
		return models;
	}

	/**
	 * 根据ID获取联系人信息
	 * 
	 * @param context
	 * @param id
	 * @return
	 */
	public static ContactDataModel getContact(Context context, String id,
			String name) {
		ContactDataModel model = new ContactDataModel();
		model.id = id;
		model.name = name;
		if (id != null) {
			// 获取号码
			String where = ContactsContract.Data.CONTACT_ID + " = " + id
					+ " AND " + ContactsContract.Data.MIMETYPE + " = '"
					+ ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
					+ "'";
			Cursor cursor = context.getContentResolver().query(
					ContactsContract.Data.CONTENT_URI, null, where, null, null);
			if (cursor.getCount() > 0) {
				while (cursor.moveToNext()) {
					PhoneModel phoneModel = new PhoneModel();
					phoneModel.type = cursor.getInt(cursor
							.getColumnIndex(PhoneModel.TYPE));
					phoneModel.number = getStrFormCursor(cursor,
							PhoneModel.NUMBER);
					phoneModel.label = getStrFormCursor(cursor,
							PhoneModel.LABEL);
					model.phones.add(phoneModel);
				}
			}
			cursor.close();

			// 获取EMail
			where = ContactsContract.Data.CONTACT_ID + " = " + id + " AND "
					+ ContactsContract.Data.MIMETYPE + " = '"
					+ ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE
					+ "'";
			cursor = context.getContentResolver().query(
					ContactsContract.Data.CONTENT_URI, null, where, null, null);
			if (cursor.getCount() > 0) {
				while (cursor.moveToNext()) {
					EMailModel eMailModel = new EMailModel();
					eMailModel.type = cursor.getInt(cursor
							.getColumnIndex(EMailModel.TYPE));
					eMailModel.address = getStrFormCursor(cursor,
							EMailModel.ADDRESS);
					eMailModel.label = getStrFormCursor(cursor,
							EMailModel.LABEL);
					model.emails.add(eMailModel);
				}
			}
			cursor.close();
		} else {
			LogUtil.e(TAG, "ID" + context.getString(R.string.error_null));
		}
		LogUtil.d(TAG, model.toString());
		return model;
	}

	private static String getStrFormCursor(Cursor cursor, String columnName) {
		String str = cursor.getString(cursor.getColumnIndex(columnName));
		return str == null ? "" : str;
	}

	private static void inserContact(Context context, ContactDataModel model) {

		ContentValues values = new ContentValues();
		/*
		 * 首先向RawContacts.CONTENT_URI执行一个空值插入，目的是获得系统返回的rawContactId
		 */
		Uri rawContactUri = context.getContentResolver().insert(
				RawContacts.CONTENT_URI, values);
		long rawContactId = ContentUris.parseId(rawContactUri);

		// 往data表里写入姓名数据
		values.clear();
		values.put(Data.RAW_CONTACT_ID, rawContactId);
		values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE); // 内容类型
		values.put(StructuredName.GIVEN_NAME, model.name);
		context.getContentResolver().insert(
				android.provider.ContactsContract.Data.CONTENT_URI, values);

		for (int i = 0; i < model.phones.size(); i++) {

		}
		// 往data表里写入电话数据
		values.clear();
		values.put(Data.RAW_CONTACT_ID, rawContactId);
		values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
		values.put(Phone.NUMBER, "13921009789");
		values.put(Phone.TYPE, Phone.TYPE_MOBILE);
		context.getContentResolver().insert(
				android.provider.ContactsContract.Data.CONTENT_URI, values);

		// 往data表里写入Email的数据
		values.clear();
		values.put(Data.RAW_CONTACT_ID, rawContactId);
		values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
		values.put(Email.DATA, "liming@itcast.cn");
		values.put(Email.TYPE, Email.TYPE_WORK);
		context.getContentResolver().insert(
				android.provider.ContactsContract.Data.CONTENT_URI, values);
	}

	/*
	 * 批量添加，处于用一个事务中
	 */
	public static void testSave(Context contex) {
		ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
		int rawContactInsertIndex = ops.size();
		ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
				.withValue(RawContacts.ACCOUNT_TYPE, null)
				.withValue(RawContacts.ACCOUNT_NAME, null).build());

		ops.add(ContentProviderOperation
				.newInsert(Data.CONTENT_URI)
				.withValueBackReference(Data.RAW_CONTACT_ID,
						rawContactInsertIndex)
				.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
				.withValue(StructuredName.DISPLAY_NAME, "良辰").build());

		ops.add(ContentProviderOperation
				.newInsert(Data.CONTENT_URI)
				.withValueBackReference(Data.RAW_CONTACT_ID,
						rawContactInsertIndex)
				.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
				.withValue(Phone.NUMBER, "1234567890")
				.withValue(Phone.TYPE, Phone.TYPE_MOBILE)
				.withValue(Phone.LABEL, "手机号").build());

		ops.add(ContentProviderOperation
				.newInsert(Data.CONTENT_URI)
				.withValueBackReference(Data.RAW_CONTACT_ID,
						rawContactInsertIndex)
				.withValue(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE)
				.withValue(Email.DATA, "liangchen@itcast.cn")
				.withValue(Email.TYPE, Email.TYPE_WORK).build());
		ContentProviderResult[] results;
		try {
			results = contex.getContentResolver().applyBatch(
					ContactsContract.AUTHORITY, ops);
			for (ContentProviderResult result : results) {
				LogUtil.i(TAG, result.uri.toString());
			}
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (OperationApplicationException e) {
			e.printStackTrace();
		}
	}
	
	public static void saveContactInfo(Context context, ContactDataModel mode) {
		ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
		int rawContactInsertIndex = ops.size();
		ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
				.withValue(RawContacts.ACCOUNT_TYPE, null)
				.withValue(RawContacts.ACCOUNT_NAME, null).build());

		ops.add(ContentProviderOperation
				.newInsert(Data.CONTENT_URI)
				.withValueBackReference(Data.RAW_CONTACT_ID,
						rawContactInsertIndex)
				.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
				.withValue(StructuredName.DISPLAY_NAME, mode.name).build());
		
		for (PhoneModel phoneModel : mode.phones) {
			ops.add(ContentProviderOperation
					.newInsert(Data.CONTENT_URI)
					.withValueBackReference(Data.RAW_CONTACT_ID,
							rawContactInsertIndex)
					.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
					.withValue(Phone.NUMBER, phoneModel.number)
					.withValue(Phone.TYPE, Phone.TYPE_MOBILE)
					.withValue(Phone.LABEL, phoneModel.label).build());
		}

		for (EMailModel emailMode : mode.emails) {
			ops.add(ContentProviderOperation
					.newInsert(Data.CONTENT_URI)
					.withValueBackReference(Data.RAW_CONTACT_ID,
							rawContactInsertIndex)
					.withValue(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE)
					.withValue(Email.DATA, emailMode.address)
					.withValue(Email.TYPE, Email.TYPE_WORK).build());
		}

		
		ContentProviderResult[] results;
		try {
			results = context.getContentResolver().applyBatch(
					ContactsContract.AUTHORITY, ops);
			for (ContentProviderResult result : results) {
				LogUtil.i(TAG, result.uri.toString());
			}
		} catch (RemoteException e) {
			e.printStackTrace();
		} catch (OperationApplicationException e) {
			e.printStackTrace();
		}
	}

}
